with Ada.Text_Io; use Ada.Text_Io;
with Projet_Types; use Projet_Types;
with Projet_Prestation; use Projet_Prestation;
with Projet_Types.Io; use Projet_Types.Io;

Package body Projet_Resultat is

  procedure Lister (Bul : Bulletin) is
     Aux : Bulletin;
     function Resumer (Un_Bulletin : Bulletin) return Bulletin is
        Vide : Matieres (1 .. 0);
        function Parcours (A_Parcourir, Retenues : Matieres;
                           Poids_En_Attente, Poids_Total : Natural;
                           Points_Acquis : Natural) return Bulletin is
        begin
           if A_Parcourir'Length =  0 then
              if poids_en_attente = 0 then
                 return
                   (Nb_Matieres => 0,
                    Objectif => Points_Acquis / Poids_Total,
                    Les_Matieres => new Matieres'(Vide));
              elsif Points_Acquis > Un_Bulletin.Objectif * Poids_Total then
                 return
                   (Nb_Matieres => 0,
                    Objectif => Points_Acquis / Poids_Total,
                    Les_Matieres =>new Matieres'(Vide));
              elsif Un_Bulletin.Objectif * Poids_Total >
                Points_Acquis + Poids_En_Attente * 2000 then
                 return
                   (Nb_Matieres => 0,
                    Objectif => (Points_Acquis + Poids_En_Attente * 2000) / Poids_En_Attente,
                    Les_Matieres =>new Matieres'(Vide));
              else
                 return
                   (Nb_Matieres => Retenues'Length,
                    Objectif =>
                      (Un_Bulletin.Objectif * Poids_Total - Points_Acquis) /
                      Poids_En_Attente,
                    Les_Matieres => new Matieres'(Retenues));
              end if;
           else
              case A_Parcourir (A_Parcourir'First).Une_Note.Selon is
                 when LIBRE =>
                    return
                      Parcours
                      (A_Parcourir => A_Parcourir (A_Parcourir'First + 1 .. A_Parcourir'Last),
                       Retenues => Retenues & A_Parcourir (A_Parcourir'First),
                       Poids_En_Attente => Poids_En_Attente + A_Parcourir (A_Parcourir'First).Un_Coefficient,
                       Poids_Total=> Poids_Total + A_Parcourir (A_Parcourir'First).Un_Coefficient,
                       Points_Acquis => Points_Acquis);
                 when Attribuee =>
                    return
                      Parcours
                      (A_Parcourir => A_Parcourir (A_Parcourir'First + 1 .. A_Parcourir'Last),
                       Retenues => Retenues,
                       Poids_En_Attente => Poids_En_Attente,
                       Poids_Total=> Poids_Total + A_Parcourir (A_Parcourir'First).Un_Coefficient,
                       Points_Acquis =>
                         (Points_Acquis
                            + (A_Parcourir (A_Parcourir'First).Une_Note.Une_Valeur
                                 * A_Parcourir (A_Parcourir'First).Un_Coefficient)));
                 when Simulee =>
                    return
                      Parcours
                      (A_Parcourir => A_Parcourir (A_Parcourir'First + 1 .. A_Parcourir'Last),
                       Retenues => Retenues,
                       Poids_En_Attente => Poids_En_Attente,
                       Poids_Total=> Poids_Total + A_Parcourir (A_Parcourir'First).Un_Coefficient,
                       Points_Acquis =>
                         (Points_Acquis
                            + (A_Parcourir (A_Parcourir'First).Une_Note.Valeur_Sim
                                 * A_Parcourir (A_Parcourir'First).Un_Coefficient)));

              end case;
           end if;
        end Parcours;
     begin
        return
          Parcours (A_Parcourir => Un_Bulletin.Les_Matieres.all,
                    Retenues => Vide,
                    Poids_En_Attente => 0,
                    Poids_Total => 0,
                    Points_Acquis => 0);
     end Resumer;


  begin

     --affichage de l'objectif
     Put("objectif fixe : " & Valeur'Image(Bul.Objectif /100) & "," & valeur'Image(Bul.objectif mod 100) );
     --affichage du bulletin
     for I in Bul.Les_Matieres.all'First..Bul.Les_Matieres.all'Last loop
         Ada.Text_IO.Set_Col (1);
         Ada.Text_IO.Put ('"' & Bul.Les_Matieres.all(I).Un_Intitule & '"');
         Ada.Text_IO.Set_Col (30);
         Ada.Text_IO.Put (Coefficient'Image(Bul.Les_Matieres.all(I).Un_Coefficient));
         Ada.Text_IO.Set_Col (35);
         Ada.Text_IO.Put (Etat'Image (Bul.Les_Matieres.all(I).Une_Note.Selon));
         if Bul.Les_Matieres.all(I).Une_Note.Selon = ATTRIBUEE then
            Ada.Text_IO.Set_Col (50);
            afficher_notes (Bul.Les_Matieres.all(I).Une_Note.Une_Valeur);
         elsif Bul.Les_Matieres.all(I).Une_Note.Selon = SIMULEE then
            Ada.Text_IO.Set_Col (50);
            afficher_notes(Bul.Les_Matieres.all(I).Une_Note.Valeur_Sim);
         end if;
         Ada.Text_IO.New_Line;
     end loop;

     Aux := Resumer(Bul);

     if Aux.Nb_Matieres = 0 then
        if Aux.Objectif < Bul.Objectif then
           Put("la moyenne maximale sera de : "& Valeur'Image(Aux.Objectif /100)&","&Valeur'Image(Aux.Objectif mod 100));
        else
           Put("la moyenne est de : "& Valeur'Image(Aux.Objectif /100)&","&Valeur'Image(Aux.Objectif mod 100));
        end if;
     else
        Put("la note moyenne a atteindre sur les matieres suivantes est : "&Valeur'Image(Aux.Objectif /100)&","&Valeur'Image(Aux.Objectif mod 100));
        for I in Aux.Les_Matieres.all'First..Aux.Les_Matieres.all'Last loop
           Ada.Text_IO.Set_Col (1);
           Ada.Text_IO.Put ('"' & Aux.Les_Matieres.all(I).Un_Intitule & '"');
           Ada.Text_Io.New_Line;
        end loop;
     end if;
  end Lister;
end Projet_Resultat;
